from django.db import models
from django.utils import timezone
from users.models import User
import json


class ScheduledTask(models.Model):
    """定时任务模型"""
    TASK_TYPES = (
        ('ui_suite', 'UI测试套件'),
        ('api_suite', 'API测试套件'),
        ('ui_case', 'UI测试用例'),
        ('api_case', 'API测试用例'),
    )
    STATUS_CHOICES = (
        ('active', '激活'),
        ('paused', '暂停'),
        ('completed', '完成'),
        ('failed', '失败'),
    )
    TRIGGER_TYPES = (
        ('cron', 'Cron表达式'),
        ('interval', '间隔时间'),
        ('date', '指定时间'),
    )

    name = models.CharField(max_length=200, verbose_name="任务名称")
    task_type = models.CharField(max_length=20, choices=TASK_TYPES, verbose_name="任务类型")
    target_id = models.IntegerField(verbose_name="目标ID")  # 套件ID或用例ID

    # 触发器配置
    trigger_type = models.CharField(max_length=20, choices=TRIGGER_TYPES, default='cron', verbose_name="触发器类型")
    cron_expression = models.CharField(max_length=100, blank=True, verbose_name="Cron表达式")
    interval_seconds = models.IntegerField(default=0, verbose_name="间隔秒数")
    scheduled_time = models.DateTimeField(blank=True, null=True, verbose_name="计划时间")

    # 执行配置
    environment_id = models.IntegerField(blank=True, null=True, verbose_name="环境ID")
    parameters = models.TextField(default='{}', blank=True, verbose_name="执行参数")

    # 状态信息
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='active', verbose_name="任务状态")
    last_run_time = models.DateTimeField(blank=True, null=True, verbose_name="最后执行时间")
    last_run_result = models.CharField(max_length=20, blank=True, verbose_name="最后执行结果")
    next_run_time = models.DateTimeField(blank=True, null=True, verbose_name="下次执行时间")

    # 统计信息
    total_runs = models.IntegerField(default=0, verbose_name="总执行次数")
    success_runs = models.IntegerField(default=0, verbose_name="成功次数")
    failure_runs = models.IntegerField(default=0, verbose_name="失败次数")

    created_by = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name="创建人", related_name='task_scheduled_tasks')
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
    updated_at = models.DateTimeField(auto_now=True, verbose_name="更新时间")

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = "定时任务"
        verbose_name_plural = "定时任务"
        ordering = ['-created_at']


class TaskExecution(models.Model):
    """任务执行记录"""
    task = models.ForeignKey(ScheduledTask, on_delete=models.CASCADE, verbose_name="定时任务")
    started_at = models.DateTimeField(auto_now_add=True, verbose_name="开始时间")
    finished_at = models.DateTimeField(blank=True, null=True, verbose_name="结束时间")
    status = models.CharField(max_length=20, choices=(
        ('running', '执行中'),
        ('success', '成功'),
        ('failed', '失败'),
        ('stopped', '已停止'),
    ), default='running', verbose_name="执行状态")
    execution_log = models.TextField(blank=True, verbose_name="执行日志")
    result_data = models.TextField(default='{}', blank=True, verbose_name="结果数据")

    def __str__(self):
        return f"{self.task.name} - {self.started_at}"

    class Meta:
        verbose_name = "任务执行记录"
        verbose_name_plural = "任务执行记录"
        ordering = ['-started_at']


# === 测试平台核心模型 ===

class TestSuite(models.Model):
    """测试套件模型"""
    SUITE_TYPES = [
        ('api', 'API测试'),
        ('ui', 'UI测试'),
        ('mixed', '混合测试')
    ]

    name = models.CharField(max_length=200, verbose_name="套件名称")
    description = models.TextField(blank=True, verbose_name="描述")
    suite_type = models.CharField(max_length=10, choices=SUITE_TYPES, verbose_name="测试类型")
    # 修复冲突：添加 related_name
    created_by = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name="创建人",
                                  related_name='task_testsuites')
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
    updated_at = models.DateTimeField(auto_now=True, verbose_name="更新时间")

    class Meta:
        verbose_name = "测试套件"
        verbose_name_plural = verbose_name
        ordering = ['-created_at']

    def __str__(self):
        return self.name


class TestCase(models.Model):
    """测试用例模型"""
    PRIORITY_CHOICES = [
        (1, '低'),
        (2, '中'),
        (3, '高')
    ]

    suite = models.ForeignKey(TestSuite, on_delete=models.CASCADE, verbose_name="所属套件")
    name = models.CharField(max_length=200, verbose_name="用例名称")
    description = models.TextField(blank=True, verbose_name="用例描述")
    # 修复：将 JSONField 改为 TextField
    config = models.TextField(default='{}', verbose_name="测试配置")
    priority = models.IntegerField(choices=PRIORITY_CHOICES, default=2, verbose_name="优先级")
    order = models.IntegerField(default=0, verbose_name="执行顺序")
    is_active = models.BooleanField(default=True, verbose_name="是否启用")
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")

    class Meta:
        verbose_name = "测试用例"
        verbose_name_plural = verbose_name
        ordering = ['suite', 'order', 'id']

    def __str__(self):
        return f"{self.suite.name} - {self.name}"

    def get_config(self):
        """获取配置字典"""
        import json
        try:
            return json.loads(self.config) if self.config else {}
        except json.JSONDecodeError:
            return {}


class TestExecution(models.Model):
    """测试执行记录模型"""
    STATUS_CHOICES = [
        ('pending', '等待中'),
        ('running', '执行中'),
        ('success', '成功'),
        ('failed', '失败'),
        ('error', '错误')
    ]

    suite = models.ForeignKey(TestSuite, on_delete=models.CASCADE, verbose_name="测试套件")
    status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='pending', verbose_name="执行状态")
    started_at = models.DateTimeField(auto_now_add=True, verbose_name="开始时间")
    finished_at = models.DateTimeField(null=True, blank=True, verbose_name="结束时间")
    total_cases = models.IntegerField(default=0, verbose_name="总用例数")
    passed_cases = models.IntegerField(default=0, verbose_name="通过用例数")
    failed_cases = models.IntegerField(default=0, verbose_name="失败用例数")
    execution_log = models.TextField(blank=True, verbose_name="执行日志")
    # 修复冲突：添加 related_name
    created_by = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name="执行人",
                                  related_name='task_testexecutions')

    class Meta:
        verbose_name = "测试执行"
        verbose_name_plural = verbose_name
        ordering = ['-started_at']

    def __str__(self):
        return f"{self.suite.name} - {self.started_at.strftime('%Y-%m-%d %H:%M')}"


class TestReport(models.Model):
    """测试报告模型"""
    execution = models.OneToOneField(TestExecution, on_delete=models.CASCADE, verbose_name="执行记录")
    # 修复：将 JSONField 改为 TextField
    report_data = models.TextField(default='{}', verbose_name="报告数据")
    summary = models.TextField(blank=True, verbose_name="报告摘要")
    generated_at = models.DateTimeField(auto_now_add=True, verbose_name="生成时间")
    download_url = models.CharField(max_length=500, blank=True, verbose_name="下载链接")

    class Meta:
        verbose_name = "测试报告"
        verbose_name_plural = verbose_name
        ordering = ['-generated_at']

    def __str__(self):
        return f"{self.execution.suite.name} - 测试报告"

    def get_report_data(self):
        """获取报告数据字典"""
        import json
        try:
            return json.loads(self.report_data) if self.report_data else {}
        except json.JSONDecodeError:
            return {}